#include "linkedqueue.h"
#include <stdlib.h>
#include <stdio.h>

// processor definitions
#include "inc/lm4f120h5qr.h"


#include "inc/hw_types.h"
#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/timer.h"
#include "driverlib/adc.h"

#include "utils/uartstdio.h"
#include "driverlib/uart.h"

#include "inc/hw_sysctl.h"
#include "inc/hw_gpio.h"	//for unlocking

#include "uart.h"		//custom uart functions


#define PA_0 GPIO_PIN_0	//0x00000001
#define PA_1 GPIO_PIN_1	//0x00000002
#define PA_2 GPIO_PIN_2	//0x00000004
#define PA_3 GPIO_PIN_3	//0x00000008
#define PA_4 GPIO_PIN_4	//0x00000010
#define PA_5 GPIO_PIN_5	//0x00000020
#define PA_6 GPIO_PIN_6	//0x00000040
#define PA_7 GPIO_PIN_7	//0x00000080

#define PB_0 GPIO_PIN_0	//0x00000001
#define PB_1 GPIO_PIN_1	//0x00000002
#define PB_2 GPIO_PIN_2	//0x00000004
#define PB_3 GPIO_PIN_3	//0x00000008
#define PB_4 GPIO_PIN_4	//0x00000010
#define PB_5 GPIO_PIN_5	//0x00000020
#define PB_6 GPIO_PIN_6	//0x00000040
#define PB_7 GPIO_PIN_7	//0x00000080

#define PC_0 GPIO_PIN_0	//0x00000001
#define PC_1 GPIO_PIN_1	//0x00000002
#define PC_2 GPIO_PIN_2	//0x00000004
#define PC_3 GPIO_PIN_3	//0x00000008
#define PC_4 GPIO_PIN_4	//0x00000010
#define PC_5 GPIO_PIN_5	//0x00000020
#define PC_6 GPIO_PIN_6	//0x00000040
#define PC_7 GPIO_PIN_7	//0x00000080

#define PD_0 GPIO_PIN_0	//0x00000001
#define PD_1 GPIO_PIN_1	//0x00000002
#define PD_2 GPIO_PIN_2	//0x00000004
#define PD_3 GPIO_PIN_3	//0x00000008
#define PD_4 GPIO_PIN_4	//0x00000010
#define PD_5 GPIO_PIN_5	//0x00000020
#define PD_6 GPIO_PIN_6	//0x00000040
#define PD_7 GPIO_PIN_7	//0x00000080

#define PE_0 GPIO_PIN_0	//0x00000001
#define PE_1 GPIO_PIN_1	//0x00000002
#define PE_2 GPIO_PIN_2	//0x00000004
#define PE_3 GPIO_PIN_3	//0x00000008
#define PE_4 GPIO_PIN_4	//0x00000010
#define PE_5 GPIO_PIN_5	//0x00000020
#define PE_6 GPIO_PIN_6	//0x00000040
#define PE_7 GPIO_PIN_7	//0x00000080

#define PF_0 GPIO_PIN_0	//0x00000001
#define PF_1 GPIO_PIN_1	//0x00000002
#define PF_2 GPIO_PIN_2	//0x00000004
#define PF_3 GPIO_PIN_3	//0x00000008
#define PF_4 GPIO_PIN_4	//0x00000010
#define PF_5 GPIO_PIN_5	//0x00000020
#define PF_6 GPIO_PIN_6	//0x00000040
#define PF_7 GPIO_PIN_7	//0x00000080

#define redled GPIO_PIN_1
#define bluled GPIO_PIN_2
#define grnled GPIO_PIN_3

#define btn1 PF_0
#define btn2 PF_4


int delay(int time);
unsigned long ulPeriod;
int count = 0;
int flip = 0;
int readValue = 0;
int qerror[2] = {0, 0};
int qstatus=0;
int drive_go = 0x01;




extern void Timer0IntHandler(void);
extern void PortAIntHandler(void);
extern void PortFIntHandler(void);
extern void UART0IntHandler(void);
extern void UART4IntHandler(void);
void PortUnlock(void);
void initPWM(int freq);
extern void pwmHandler(void);
void pwmSetDuty(int duty_cycle);
void initADC0(void);

int stepperInit(int, int);
int step(int, int, int);
void belt_driver(int);

int main(void) {

	//mainvars
	int Count=0;
	//enable clock, 200MHz/5 = 40MHz
	ROM_SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);
	
	//enable clock, use crystal at 1MHz
	//ROM_SysCtlClockSet(SYSCTL_RCC_XTAL_1MHZ | SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN);

	// enable PORT A,B,D,E,F GPIO and Timer0 peripheral
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA|SYSCTL_PERIPH_GPIOB|SYSCTL_PERIPH_GPIOC|SYSCTL_PERIPH_GPIOD|SYSCTL_PERIPH_GPIOE|SYSCTL_PERIPH_GPIOF);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);
	ROM_SysCtlDelay(200000);

	//unlock PD7
	PortUnlock();

	// set LED PORT D pins as outputs
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, (PD_0 | PD_1 | PD_2 | PD_3 | PD_4 | PD_5));
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, (PA_5 | PA_6 | PA_7));
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, (PB_3 | PB_4));
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, redled|bluled|grnled);

	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, (PA_2 | PA_3 | PA_4));
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, (PD_6 | PD_7));
	
	// set Port A 2,3,4 and Port B 6,7 as inputs
	//ROM_GPIOPinTypeGPIOInput(GPIO_PORTA_BASE, (PA_2 | PA_3 | PA_4));
	//ROM_GPIOPinTypeGPIOInput(GPIO_PORTD_BASE, (PD_6 | PD_7));
	ROM_GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, (btn1|btn2));

	// set Port B and E stepper pins as output
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, (PB_5 | PB_0 | PB_1));
	ROM_GPIOPinTypeGPIOOutput(GPIO_PORTE_BASE, (PE_4 | PE_5 | PE_1));

	//setup pwm
	initPWM(500);
	pwmSetDuty(150);
	//initADC0();

	//set timer period: 40MHz/10/2 = 2MHz = 0.5us
	//for 1000us = 1ms use Div by 0.1 and then 4, 40MHz / 0.1 / 4 = 1ms
	ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);
	ulPeriod = (ROM_SysCtlClockGet() / 1 / 1);		//for 1ms
	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod - 1);

	//GPIO interrupt setup
	//ROM_GPIOPinIntEnable(GPIO_PORTA_BASE, PA_2);		//added
	ROM_GPIOPinIntEnable(GPIO_PORTF_BASE, (btn1|btn2));

	//ROM_GPIOIntTypeSet(GPIO_PORTA_BASE, PA_2, GPIO_FALLING_EDGE);
	//ROM_GPIOPadConfigSet(GPIO_PORTA_BASE, PA_2, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

	ROM_GPIOIntTypeSet(GPIO_PORTF_BASE, (btn1|btn2), GPIO_FALLING_EDGE);
	ROM_GPIOPadConfigSet(GPIO_PORTF_BASE, (btn1|btn2), GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
	
	//initial interrupt clear
	//ROM_GPIOPinIntClear(GPIO_PORTA_BASE, PA_2);
	ROM_GPIOPinIntClear(GPIO_PORTF_BASE, (btn1|btn2));

	ROM_IntEnable(INT_GPIOA);	//works!!!!!
	ROM_IntEnable(INT_GPIOF);

	//set up UART 
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART4);
	//usb virtual uart
	ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
	ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
	//bluetooth uart
	ROM_GPIOPinConfigure(GPIO_PC4_U4RX);
	ROM_GPIOPinConfigure(GPIO_PC5_U4TX);
	
	//define ports and pins used for uart
	ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, (PA_0|PA_1));
	ROM_GPIOPinTypeUART(GPIO_PORTC_BASE, (PC_4|PC_5));
	
	//enable uart interrupts
	ROM_IntEnable(INT_UART0);
	ROM_IntEnable(INT_UART4);
	
	//enable input and output interrupts for uart
	ROM_UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_TX);
	ROM_UARTIntEnable(UART4_BASE, UART_INT_RX | UART_INT_TX);
	
	//set up uart speeds, virtual usb uses 115200, bluetooth uses 9600 (can change using AT commands)
	ROM_UARTConfigSetExpClk(UART0_BASE, ROM_SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE));
	ROM_UARTConfigSetExpClk(UART4_BASE, ROM_SysCtlClockGet(), 9600, (UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE));

	//send test uart
	bt_UARTsend("\033[2J");				//clear screen
	bt_UARTsend("Initializing System....\r\n");
	bt_UARTsend("Welcome to Stellarilink\r\n");


	//Timer interrupt setup
	ROM_TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
	ROM_IntEnable(INT_TIMER0A);
	ROM_TimerEnable(TIMER0_BASE, TIMER_A);
	
	//enable all interrupts
	ROM_IntMasterEnable();
	
	//init pins as low
	ROM_GPIOPinWrite(GPIO_PORTD_BASE, 0xff, 0);
	
	//initialize Queue
	if(!QueueInit()) bt_UARTsend("Queue Initialized\r\n");
	
	// loop forever
	//step(300, 1, 600000);
	while(1)
	{
		//belt_driver(drive_go);
		//ROM_SysCtlDelay(5000000);
		//belt_driver(2);
		step(17,1,200000);
		ROM_SysCtlDelay(5000000);
		step(34,1,200000);
		ROM_SysCtlDelay(5000000);
		step(100,1,200000);
		ROM_SysCtlDelay(5000000);
		step(17,0,200000);
		ROM_SysCtlDelay(5000000);
		step(34,0,200000);
		ROM_SysCtlDelay(5000000);
		step(100,0,200000);
		ROM_SysCtlDelay(5000000);
		//belt_driver(0);
		//ROM_SysCtlDelay(5000000);
	}
}

void Timer0IntHandler(void)
{
	//clear interrupt
	ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);	
	/*if(qstatus) {
		switch(count)
		{
			case 0:	{
					//bt_UARTsend("case 0\r\n");
					ROM_GPIOPinWrite(GPIO_PORTA_BASE, PA_7, (PA_7*Queue[count]));
					ROM_GPIOPinWrite(GPIO_PORTA_BASE, PA_6, (PA_6*Queue[count+1]));
				} break;
			case 1: {
					//bt_UARTsend("case 1\r\n");
					ROM_GPIOPinWrite(GPIO_PORTA_BASE, PA_5, (PA_5*Queue[count+1]));
					ROM_GPIOPinWrite(GPIO_PORTB_BASE, PB_4, (PB_4*Queue[count+2]));
				} break;
			case 2: {
					//bt_UARTsend("case 2\r\n");
					ROM_GPIOPinWrite(GPIO_PORTD_BASE, PD_3, (PD_3*Queue[count+2]));
					ROM_GPIOPinWrite(GPIO_PORTD_BASE, PD_2, (PD_2*Queue[count+3]));
				} break;
			case 3: {
					ROM_GPIOPinWrite(GPIO_PORTA_BASE, (PA_4|PA_5|PA_6|PA_7), 0x00);
					ROM_GPIOPinWrite(GPIO_PORTB_BASE, PB_4, 0x00);
					ROM_GPIOPinWrite(GPIO_PORTD_BASE, (PD_2|PD_3), 0x00);
				} break;
			default: break;
	
		}
		count++;
		count %= 4;
	}*/

	//reset counter value back to ulPeriod
	ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, ulPeriod-1);

	//bt_UARTsend("timer\n");
	flip ^= 0xff;
	ROM_GPIOPinWrite(GPIO_PORTF_BASE, bluled, flip);
	
}

void PortAIntHandler(void)
{
	//moved interrupt clear to end to prevent bouncing since it's too fast
	//ROM_GPIOPinIntClear(GPIO_PORTA_BASE, PA_2);

	ROM_GPIOPinWrite(GPIO_PORTF_BASE, redled, redled);
	
	//re-init readValue
	readValue = 0;
	
	//read from pins
	/*
	if(ROM_GPIOPinRead(GPIO_PORTD_BASE, PD_7)) readValue |= 0x100;
	if(ROM_GPIOPinRead(GPIO_PORTA_BASE, PA_4)) readValue |= 0x010;
	if(ROM_GPIOPinRead(GPIO_PORTA_BASE, PA_3)) readValue |= 0x001;
	

	switch(readValue)
	{
		case 0x110: break;	//high level nothing read
		case 0x010: 	qerror[0] = QueuePut(0);
				qerror[1] = QueuePut(1);
				if(!qerror[0] | !qerror[1])
				{
					bt_UARTsend("In: 0x10\r\n");
					break;
				} else if((qerror[0] == -1) | (qerror[1] == -1))
				{
					bt_UARTsend("Queue Full\r\n");
					qstatus = 1;
					break;
				}
		case 0x101: break;
		case 0x001: 	qerror[0] = QueuePut(1);
				qerror[1] = QueuePut(0);
				if(!qerror[0] | !qerror[1])
				{
					bt_UARTsend("In: 0x01\r\n");
					break;
				} else if((qerror[0] == -1) | (qerror[1] == -1))
				{
					bt_UARTsend("Queue Full\r\n");
					qstatus = 1;
					break;
				}
		case 0x100: break;
		case 0x000: 	qerror[0] = QueuePut(0);
				qerror[1] = QueuePut(0);
				if(!qerror[0] | !qerror[1])
				{
					bt_UARTsend("In: 0x00\r\n");
					break;
				} else if((qerror[0] == -1) | (qerror[1] == -1))
				{
					bt_UARTsend("Queue Full\r\n");
					qstatus = 1;
					break;
				}
		case 0x111: break;
		case 0x011: 	qerror[0] = QueuePut(1);
				qerror[1] = QueuePut(1);
				if(!qerror[0] | !qerror[1])
				{
					bt_UARTsend("In: 0x11\r\n");
					break;
				} else if((qerror[0] == -1) | (qerror[1] == -1))
				{
					bt_UARTsend("Queue Full\r\n");
					qstatus = 1;
					break;
				}
		default: break;
	}
	*/
	ROM_SysCtlDelay(2000000);
	ROM_GPIOPinIntClear(GPIO_PORTA_BASE, PA_2);		//clear interrupt here to prevent softbouce
	ROM_GPIOPinWrite(GPIO_PORTF_BASE, redled, redled);
}

void PortFIntHandler(void)
{
	ROM_GPIOPinIntClear(GPIO_PORTF_BASE, (btn1|btn2));
	//ROM_GPIOPinIntClear(GPIO_PORTF_BASE, (btn1|btn2));
	
	//clear leds
	//ROM_GPIOPinWrite(GPIO_PORTA_BASE, 0xff, 0);
	//ROM_GPIOPinWrite(GPIO_PORTD_BASE, 0xff, 0);

	//bt_UARTsend("\033[2J");		//clear screen
	bt_UARTsend("Port F interrupt\r\n");
	
	
	belt_driver(drive_go);
	drive_go ^= drive_go;
}

void UART0IntHandler(void)
{
	unsigned long ulStatus;

	ulStatus = ROM_UARTIntStatus(UART0_BASE, true);
	ROM_UARTIntClear(UART0_BASE, ulStatus);
	while(ROM_UARTCharsAvail(UART0_BASE))
	{
		ROM_UARTCharPutNonBlocking(UART0_BASE, ROM_UARTCharGetNonBlocking(UART0_BASE));
	}
}

void UART4IntHandler(void)
{
	unsigned long ulStatus;

	ulStatus = ROM_UARTIntStatus(UART4_BASE, true);
	ROM_UARTIntClear(UART4_BASE, ulStatus);
	while(ROM_UARTCharsAvail(UART4_BASE))
	{
		ROM_UARTCharPutNonBlocking(UART4_BASE, ROM_UARTCharGetNonBlocking(UART4_BASE));
	}
}



void PortUnlock(void)
{
	//unlock gpio pin PD7 since it's used as a special function
	HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
	HWREG(GPIO_PORTD_BASE + GPIO_O_CR) |= 0x80;
	HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = 0;

}

//------Stepping Out!
int stepperInit(int coil, int delay)
{
	//define pins here for future reassignment
	#define E1 PA_7 	//PB_5
	#define L1 PA_6		//PB_0
	#define L2 PA_5		//PB_1
	#define E2 PD_3		//PE_4
	#define L3 PD_2		//PE_5
	#define L4 PD_1		//PE_1
	#define Low 0x00

	//bt_UARTsend("Stepping\r\n");

	//depending on which coil is sent, send specific sequence
	switch(coil)
	{
		case 1: {
				//ROM_GPIOPinWrite(GPIO_PORTB_BASE, (E1 | L1 | L2), (E1 | L1));	//110
				//ROM_GPIOPinWrite(GPIO_PORTE_BASE, (E2 | L3 | L4), Low);		//000
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (E1 | L1 | L2), (E1 | L1));
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (E2 | L3 | L4), E2);
				
		

			} break;
		case 2: {
				//ROM_GPIOPinWrite(GPIO_PORTB_BASE, (E1 | L1 | L2), Low);		//000
				//ROM_GPIOPinWrite(GPIO_PORTE_BASE, (E2 | L3 | L4), (E2 | L3));	//110
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (E1 | L1 | L2), E1);
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (E2 | L3 | L4), (E2 | L3));

			} break;
		case 3: {
				//ROM_GPIOPinWrite(GPIO_PORTB_BASE, (E1 | L1 | L2), (E1 | L2));	//101
				//ROM_GPIOPinWrite(GPIO_PORTE_BASE, (E2 | L3 | L4), Low);		//000
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (E1 | L1 | L2), (E1 | L2));
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (E2 | L3 | L4), E2);

			} break;
		case 4: {
				//ROM_GPIOPinWrite(GPIO_PORTB_BASE, (E1 | L1 | L2), Low);		//000
				//ROM_GPIOPinWrite(GPIO_PORTE_BASE, (E2 | L3 | L4), (E2 | L4));	//101
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (E1 | L1 | L2), E1);
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (E2 | L3 | L4), (E2 | L4));

			} break;
		default: bt_UARTsend("Stepper motor init failed"); return 1;
	}
	ROM_SysCtlDelay(delay);
	return 0;
}

//-----Globals for Stepper
int gStepperPos = 0;
int gCurrentStep = 0;
int step(int steps, int dir, int delay)	//dir=1 for cw, 0 for ccw
{
	//Logic flow - for each step, take current step, +/- dir, repeat
	while ( steps > 0 )
	{
		if (dir)
		{
			gCurrentStep++;
			if (gCurrentStep >4)
			{
				gCurrentStep=1;
			}
			//gCurrentStep=((gCurrentStep+1)%4);
			
			//gCurrentStep=((gCurrentStep+1)%200);
		}
		else
		{
			gCurrentStep--;
			if (gCurrentStep < 1)
			{
				gCurrentStep=4;
			}
			//gCurrentStep=((gCurrentStep-1)%4);
			
			//gCurrentStep=((gCurrentStep-1)%200);
		}
		//bt_UARTsend((char)(gCurrentStep+48));
		stepperInit(gCurrentStep, delay);
		//ROM_SysCtlDelay(200000);
		steps--;
	}
}

void initADC0(void)
{
	unsigned long ulADC0_Value[1];
	unsigned long ulTemp_ValueC;
	unsigned long ulTemp_ValueF;
	char tempoutput[20];

	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);
	ROM_ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
	ROM_ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_TS | ADC_CTL_IE |
                             ADC_CTL_END);
	ROM_ADCSequenceEnable(ADC0_BASE, 3);
	ROM_ADCIntClear(ADC0_BASE, 3);

	ROM_ADCProcessorTrigger(ADC0_BASE, 3);
	while(!ROM_ADCIntStatus(ADC0_BASE, 3, false));

	ROM_ADCIntClear(ADC0_BASE, 3);

	// Read ADC Value.
	ROM_ADCSequenceDataGet(ADC0_BASE, 3, ulADC0_Value);

	ulTemp_ValueC = ((1475 * 1023) - (2250 * ulADC0_Value[0])) / 10230;
	ulTemp_ValueF = ((ulTemp_ValueC * 9) + 160) / 5;

	//sprintf(tempoutput, "%d", ulTemp_ValueC);

	bt_UARTsend(tempoutput);

	//UARTprintf("Temperature = %3d*C or %3d*F\r", ulTemp_ValueC,ulTemp_ValueF);

        //SysCtlDelay(SysCtlClockGet() / 12);
}

//-----------------------------------------------

#define PWM PA_2

//Globals for PWM
int _frequency = 0;
int _period = 0;
int _duty = 0;
int _onOff = 0;

void initPWM(int freq)
{
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER3);
	ROM_TimerConfigure(TIMER3_BASE, TIMER_CFG_PERIODIC);

	_period = (ROM_SysCtlClockGet() / freq);

	ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
	ROM_TimerIntEnable(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
	ROM_IntEnable(INT_TIMER3A);
	ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, _period-_duty-1);
	ROM_TimerEnable(TIMER3_BASE, TIMER_A);
}

void pwmHandler(void)
{
	_onOff ^= PWM;

	//first run, time = duty, second run, time = period - duty
	(_onOff) ? ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, _duty) : ROM_TimerLoadSet(TIMER3_BASE, TIMER_A, _period-_duty-1);

	//write out state
	ROM_GPIOPinWrite(GPIO_PORTA_BASE, PWM, _onOff);

	//clear interrupts
	ROM_TimerIntClear(TIMER3_BASE, TIMER_TIMA_TIMEOUT);
	//bt_UARTsend("pwm fire\r\n");
}

void pwmSetDuty(int duty_cycle)
{
	if(duty_cycle > 1000)
	{
		duty_cycle = 1000;
	}
	duty_cycle = duty_cycle*_period;
	_duty = duty_cycle/1000;
}
//--------------------------------------------

//-----------Globals for Belt Driver

//define pins here for future reassignment
#define IA PA_3
#define EA PA_4
#define EB PD_7
#define IB PD_6

int belt_dir = 0;		//0 means BREAK!!!

void belt_driver(int direction)
{
	switch(direction)
	{
		case 0: {
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), EA);
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), EB);
			} break;
		case 1: {
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), (IA|EA));
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), EB);
			} break;
		case 2: {
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), EA);
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), (IB|EB));
			} break;
		default: {
				ROM_GPIOPinWrite(GPIO_PORTA_BASE, (IA|EA), 0);
				ROM_GPIOPinWrite(GPIO_PORTD_BASE, (IB|EB), 0);
			} break;
	}
}

